﻿// -----------------------------------------------------------------------
// <copyright file="ButterWorthFilter.cs" company="">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace ImageP
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Drawing;
    using MathWorks.MATLAB.NET.Arrays;
    using MathWorks.MATLAB.NET.Utility;
    using System.Data;
    using FourierFin;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class ButterWorthFilter
    {
        Normalize norm = new Normalize();
        public int[,] normalizedBufferRed;
        public int[,] normalizedBufferGreen;
        public int[,] normalizedBufferBlue;
        public MWArray realF;
        public double[,] realBufferR, realBufferG, realBufferB, imgBufferR, imgBufferG, imgBufferB;
       private double[,] FilrealBufferR, FilrealBufferG, FilrealBufferB, FilimgBufferR, FilimgBufferG, FilimgBufferB;
        public int width, height;
        private Bitmap FilteredImg;
        Bitmap OriginalImage;
       // FourierFinclass ft = new FourierFinclass();
        public FourierT ft = new FourierT();
        
        public Bitmap lowpass(Bitmap OriginalImg,int n,double d)
        {
            this.OriginalImage = OriginalImg;
            FilrealBufferR = new double[this.OriginalImage.Height, this.OriginalImage.Width];
            FilrealBufferG = new double[this.OriginalImage.Height, this.OriginalImage.Width];
            FilrealBufferB = new double[this.OriginalImage.Height, this.OriginalImage.Width];

            FilimgBufferR = new double[this.OriginalImage.Height, this.OriginalImage.Width];
            FilimgBufferG = new double[this.OriginalImage.Height, this.OriginalImage.Width];
            FilimgBufferB = new double[this.OriginalImage.Height, this.OriginalImage.Width];
           // , FilrealBufferG, FilrealBufferB, FilimgBufferR, FilimgBufferG, FilimgBufferB
            frequencyDomain();
            double D;
            double[,] H = new double[this.OriginalImage.Height, this.OriginalImage.Width];
            for (int i = 0; i < this.OriginalImage.Height; i++)
            {
                for (int j = 0; j < this.OriginalImage.Width; j++)
                {
                    D = Math.Sqrt(Math.Pow((j - (this.OriginalImage.Width / 2)), 2) + Math.Pow((i - (this.OriginalImage.Height / 2)), 2)); 
                    
                    H[i,j]= 1/ (1+(Math.Pow((D/d) ,(2*n) ) ));



                    this.FilrealBufferR[i, j] = H[i, j] * realBufferR[i,j];
                    this.FilrealBufferG[i, j] = H[i, j] * realBufferG[i, j];
                    this.FilrealBufferB[i, j] = H[i, j] * realBufferB[i, j];
                     //this.FilrealBufferB[i, j] = 1 / (1 + (Math.Pow((D / d), (2 * n))));
                   
                    //this.FilrealBufferR[i, j] = 1 / (1 + Math.Pow((this.realBufferR[i, j] / d), 2 * n));
                    //this.FilrealBufferG[i, j] = 1 / (1 + Math.Pow((this.realBufferG[i, j] / d), 2 * n));
                    //this.FilrealBufferB[i, j] = 1 / (1 + Math.Pow((this.realBufferB[i, j] / d), 2 * n));


                    this.FilimgBufferR[i, j] = H[i, j] * imgBufferR[i, j];
                    this.FilimgBufferG[i, j] = H[i, j] * imgBufferG[i, j];
                    this.FilimgBufferB[i, j] = H[i, j] * imgBufferB[i, j];
                     
                    //this.FilimgBufferR[i, j] = 1 / (1 + Math.Pow((this.imgBufferR[i, j] / d), 2 * n));
                    //this.FilimgBufferG[i, j] = 1 / (1 + Math.Pow((this.imgBufferG[i, j] / d), 2 * n));
                    //this.FilimgBufferB[i, j] = 1 / (1 + Math.Pow((this.imgBufferB[i, j] / d), 2 * n));
                }
                
            }


            inverseFreq();
            return this.FilteredImg;
        }



       

        public Bitmap highpass(Bitmap OriginalImg, int n, double d)
        {
            this.OriginalImage = OriginalImg;
            FilrealBufferR = new double[this.OriginalImage.Height, this.OriginalImage.Width];
            FilrealBufferG = new double[this.OriginalImage.Height, this.OriginalImage.Width];
            FilrealBufferB = new double[this.OriginalImage.Height, this.OriginalImage.Width];

            FilimgBufferR = new double[this.OriginalImage.Height, this.OriginalImage.Width];
            FilimgBufferG = new double[this.OriginalImage.Height, this.OriginalImage.Width];
            FilimgBufferB = new double[this.OriginalImage.Height, this.OriginalImage.Width];

            frequencyDomain();
            double[,] H = new double[this.OriginalImage.Height, this.OriginalImage.Width];
            double D;
            for (int i = 0; i < this.OriginalImage.Height; i++)
            {
                for (int j = 0; j < this.OriginalImage.Width; j++)
                {
                    D = Math.Sqrt(Math.Pow((j - (this.OriginalImage.Width / 2)), 2) + Math.Pow((i - (this.OriginalImage.Height / 2)), 2));

                    H[i, j] =1-( 1 / (1 + (Math.Pow((D / d), (2 * n)))));



                    this.FilrealBufferR[i, j] = H[i, j] * realBufferR[i, j];
                    this.FilrealBufferG[i, j] = H[i, j] * realBufferG[i, j];
                    this.FilrealBufferB[i, j] = H[i, j] * realBufferB[i, j];


                    this.FilimgBufferR[i, j] = H[i, j] * imgBufferR[i, j];
                    this.FilimgBufferG[i, j] = H[i, j] * imgBufferG[i, j];
                    this.FilimgBufferB[i, j] = H[i, j] * imgBufferB[i, j];
                }

            }
            inverseFreq();
            return this.FilteredImg;
        }

       private void inverseFreq()
        {
             
            //inverse
            MWNumericArray inverseFreqR, inverseFreqG, inverseFreqB;
            double[,] realR, realG, realB;
            this.FilteredImg = new Bitmap(this.OriginalImage.Width, this.OriginalImage.Height);
            inverseFreqR = (MWNumericArray)ft.InvF((MWNumericArray)this.FilrealBufferR, (MWNumericArray)this.FilimgBufferR);
            inverseFreqG = (MWNumericArray)ft.InvF((MWNumericArray)this.FilrealBufferG, (MWNumericArray)this.FilimgBufferG);
            inverseFreqB = (MWNumericArray)ft.InvF((MWNumericArray)this.FilrealBufferB, (MWNumericArray)this.FilimgBufferB);
            realR = (double[,])inverseFreqR.ToArray(MWArrayComponent.Real);
            realG = (double[,])inverseFreqG.ToArray(MWArrayComponent.Real);
            realB = (double[,])inverseFreqB.ToArray(MWArrayComponent.Real);
            normalizedBufferRed = new int[this.height, this.width];
            normalizedBufferGreen = new int[this.height, this.width];
            normalizedBufferBlue = new int[this.height, this.width];

            normalizedBufferRed = norm.Normalize_imagefft(realR, this.OriginalImage.Height, this.OriginalImage.Width);
            normalizedBufferGreen = norm.Normalize_imagefft(realG, this.OriginalImage.Height, this.OriginalImage.Width);
            normalizedBufferBlue = norm.Normalize_imagefft(realB, this.OriginalImage.Height, this.OriginalImage.Width);
            for (int i = 0; i < this.OriginalImage.Height; i++)
            {
                for (int j = 0; j < this.OriginalImage.Width; j++)
                {
                    //this.FilteredImg.SetPixel(j, i, System.Drawing.Color.FromArgb(Convert.ToInt32(realR[i, j]), (Convert.ToInt32(realG[i, j])), (Convert.ToInt32(realB[i, j]))));
                    this.FilteredImg.SetPixel(j, i, System.Drawing.Color.FromArgb((normalizedBufferRed[i, j]), (normalizedBufferGreen[i, j]),(normalizedBufferBlue[i, j])));
                }
            }

        }
        private void frequencyDomain()
        {
              

              byte[,] R = new byte[this.OriginalImage.Height, this.OriginalImage.Width];
              byte[,] G = new byte[this.OriginalImage.Height, this.OriginalImage.Width];
              byte[,] B = new byte[this.OriginalImage.Height, this.OriginalImage.Width];
            Color Clr;
            for (int i = 0; i < this.OriginalImage.Height; i++)
                for (int j = 0; j < this.OriginalImage.Width; j++)
                {
                    Clr = this.OriginalImage.GetPixel(j, i);
                    R[i, j] = Clr.R;
                    G[i, j] = Clr.G;
                    B[i, j] = Clr.B;
                }

            MWArray ftsR, ftsG, ftsB;
            ftsR = (MWNumericArray)ft.FreqDomian((MWNumericArray)R);
            ftsG = (MWNumericArray)ft.FreqDomian((MWNumericArray)G);
            ftsB = (MWNumericArray)ft.FreqDomian((MWNumericArray)B);

            realBufferR = (double[,])ft.getReal(ftsR).ToArray();
            realBufferG = (double[,])ft.getReal(ftsG).ToArray();
            realBufferB = (double[,])ft.getReal(ftsB).ToArray();

            imgBufferR = (double[,])ft.getImag(ftsR).ToArray();
            imgBufferG = (double[,])ft.getImag(ftsG).ToArray();
            imgBufferB = (double[,])ft.getImag(ftsB).ToArray();




            //MWArray ftsR, ftsG, ftsB;
            //ftsR = (MWNumericArray)ft.FreqDomian((MWNumericArray)R);
            //ftsG = (MWNumericArray)ft.FreqDomian((MWNumericArray)G);
            //ftsB = (MWNumericArray)ft.FreqDomian((MWNumericArray)B);

            //MWNumericArray temp1 = (MWNumericArray)ft.getReal(ftsR);
            //MWNumericArray temp2 = (MWNumericArray)ft.getReal(ftsR);
            //MWNumericArray temp3 = (MWNumericArray)ft.getReal(ftsR);
            //realBufferR = (double[,])temp1.ToArray(MWArrayComponent.Real);
            //realBufferG = (double[,])temp2.ToArray(MWArrayComponent.Real);
            //realBufferB = (double[,])temp3.ToArray(MWArrayComponent.Real);
          

            //MWNumericArray temp4 = (MWNumericArray)ft.getImag(ftsR);
            //MWNumericArray temp5 = (MWNumericArray)ft.getImag(ftsR);
            //MWNumericArray temp6 = (MWNumericArray)ft.getImag(ftsR);

            //imgBufferR = (double[,])temp4.ToArray(MWArrayComponent.Real); ;
            //imgBufferG = (double[,])temp5.ToArray(MWArrayComponent.Imaginary);
            //imgBufferB = (double[,])temp6.ToArray(MWArrayComponent.Imaginary);



        }
    }
}

